package work.linruchang.cmd;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.stream.CollectorUtil;
import cn.hutool.core.util.ObjUtil;

import java.util.*;
import java.util.function.Function;

/**
 * @author LinRuChang
 * @version 1.0
 * @date 2023/03/27
 * @since 1.8
 **/
public interface CMD {

    /**
     * 基于进程ID获取端口号
     * @param processId
     * @return
     */
    List<Integer> getPort(Integer processId);

    /**
     * 基于进程ID获取端口号
     * @param processIds
     * @return
     */
    default Map<Integer,List<Integer>> getPorts(Collection<Integer> processIds) {
        Map<Integer,List<Integer>> result = MapUtil.newHashMap();

        CollUtil.defaultIfEmpty(processIds, Collections.emptyList()).stream()
                .distinct()
                .filter(ObjUtil::isNotNull)
                .forEach(processId -> {
                    result.put(processId,getPort(processId));
                });


        return result;
    }

    /**
     * 基于端口号获取进程ID
     * @param port
     * @return
     */
    List<Integer> getProcessId(Integer port);


    /**
     * 基于端口号获取进程ID
     * @param ports
     * @return
     */
    default Map<Integer,List<Integer>> getProcessIds(Collection<Integer> ports) {

        Map<Integer,List<Integer>> result = MapUtil.newHashMap();

        CollUtil.defaultIfEmpty(ports, Collections.emptyList()).stream()
                .distinct()
                .filter(ObjUtil::isNotNull)
                .forEach(port -> {
                    result.put(port,getProcessId(port));
                });


        return result;
    }

    /**
     * 基于进程ID杀死进程
     * @param processId 进程ID
     * @return 杀进程结果
     */
    String killProcess(Integer processId);


    /**
     * 基于端口号获取进程ID
     * @param processIds
     * @return
     */
    default Map<Integer,String> killProcesses(Collection<Integer> processIds) {
        return CollUtil.defaultIfEmpty(processIds, Collections.emptyList()).stream()
                .distinct()
                .filter(ObjUtil::isNotNull)
                .collect(CollectorUtil.toMap(Function.identity(),this::killProcess, (v1,v2) -> v2));
    }

    /**
     * 基于端口号进行杀进程
     * @param port
     */
    default String killProcessByPort(Integer port) {
        return Optional.ofNullable(port)
                .map(this::getProcessId)
                .map(this::killProcesses)
                .map(Map::toString)
                .orElse("无结果");
    }

    /**
     * 基于端口号进行杀进程
     * @param ports
     */
    default Map<Integer,String> killProcessByPorts(Collection<Integer> ports) {
        return CollUtil.defaultIfEmpty(ports, Collections.emptyList()).stream()
                .distinct()
                .filter(ObjUtil::isNotNull)
                .collect(CollectorUtil.toMap(Function.identity(),this::killProcessByPort,(v1,v2) -> v2));
    }
}
